package com.intelligent.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.intelligent.dto.InventoryDetailsQueryDTO;
import com.intelligent.mapper.InventoryDetailsMapper;
import com.intelligent.pojo.*;
import com.intelligent.service.*;
import com.intelligent.vo.InventoryDetailsVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 库存明细服务实现
 */
@Slf4j
@Service
public class InventoryDetailsServiceImpl extends ServiceImpl<InventoryDetailsMapper, InventoryDetails>
        implements InventoryDetailsService {

    @Autowired
    private ProductService productService;

    @Autowired
    private UnitService unitService;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private WarehouseReceiptService warehouseReceiptService;

    @Override
    public IPage<InventoryDetailsVO> pageList(InventoryDetailsQueryDTO query) {
        // 1. 处理产品名称和类型查询条件
        Set<Long> productIds = new HashSet<>();

        if (query.getCategory() != null) {
            LambdaQueryWrapper<Product> categoryQuery = new LambdaQueryWrapper<>();
            categoryQuery.eq(Product::getCategory, query.getCategory());
            List<Long> categoryProductIds = productService.list(categoryQuery)
                .stream()
                .map(Product::getProductId)
                .collect(Collectors.toList());
            productIds.addAll(categoryProductIds);
            if (productIds.isEmpty()) {
                return new Page<>();
            }
        }

        if (StringUtils.isNotBlank(query.getProductName())) {
            LambdaQueryWrapper<Product> nameQuery = new LambdaQueryWrapper<>();
            nameQuery.like(Product::getProductName, query.getProductName());
            List<Long> nameProductIds = productService.list(nameQuery)
                .stream()
                .map(Product::getProductId)
                .collect(Collectors.toList());

            if (productIds.isEmpty()) {
                productIds.addAll(nameProductIds);
            } else {
                productIds.retainAll(nameProductIds);
                if (productIds.isEmpty()) {
                    return new Page<>();
                }
            }
        }

        Page<InventoryDetails> page = new Page<>(
            query.getPageNum() != null ? query.getPageNum() : 1,
            query.getPageSize() != null ? query.getPageSize() : 5
        );

        LambdaQueryWrapper<InventoryDetails> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(query.getInventoryNo())) {
            wrapper.like(InventoryDetails::getInventoryNo, query.getInventoryNo());
        }

        if (!productIds.isEmpty()) {
            wrapper.in(InventoryDetails::getProductId, productIds);
        }

        if (query.getWarehouseId() != null) {
            wrapper.eq(InventoryDetails::getWarehouseId, query.getWarehouseId());
        }

        IPage<InventoryDetails> detailsPage = this.page(page, wrapper);

        return detailsPage.convert(details -> {
            InventoryDetailsVO vo = new InventoryDetailsVO();
            BeanUtils.copyProperties(details, vo);

            if (details.getProductId() != null) {
                Product product = productService.getById(details.getProductId());
                if (product != null) {
                    vo.setProductId(product.getProductId());
                    vo.setProductName(product.getProductName());
                    vo.setProductCode(product.getProductCode());
                    vo.setSpecification(product.getSpecification());
                    vo.setCategory(product.getCategory());
                    vo.setPurchasePrice(product.getPurchasePrice());
                    vo.setSalePrice(product.getSalePrice());
                }
            }

            if (details.getUnitId() != null) {
                Unit unit = unitService.getById(details.getUnitId());
                if (unit != null) {
                    vo.setUnitId(unit.getUnitId());
                    vo.setUnitName(unit.getUnitName());
                }
            }

            if (details.getWarehouseId() != null) {
                Warehouse warehouse = warehouseService.getById(details.getWarehouseId());
                if (warehouse != null) {
                    vo.setWarehouseId(warehouse.getWarehouseId());
                    vo.setWarehouseName(warehouse.getWarehouseName());
                }
            }

            if (details.getWarehouseId() != null) {
                WarehouseReceipt warehouseReceipt = warehouseReceiptService.getById(details.getId());
                if (warehouseReceipt != null) {
                    vo.setQuantity(warehouseReceipt.getQuantity());
                    vo.setStock(warehouseReceipt.getStock());
                }
            }

            return vo;
        });
    }

    @Override
    public InventoryDetails getDetailById(Long id) {
        return this.getById(id);
    }

    @Override
    public boolean add(InventoryDetails details) throws RuntimeException {
        if (details.getProductId() == null || productService.getById(details.getProductId()) == null) {
            throw new RuntimeException("产品不存在");
        }

        if (details.getUnitId() != null && details.getUnitId() != 0) {
            Unit unit = unitService.getById(details.getUnitId());
            if (unit == null) {
                throw new RuntimeException("单位不存在");
            }
        }
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String randomNum = String.format("%04d", (int)(Math.random() * 1000));
        String inventoryNo = "KC" + timestamp + randomNum;
        details.setInventoryNo(inventoryNo);

        return save(details);
    }
}
